package com.xinyi.share.weixin.message;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;

import com.xinyi.share.weixin.message.event.ClickEventMessage;
import com.xinyi.share.weixin.message.event.Event;
import com.xinyi.share.weixin.message.event.EventMessage;
import com.xinyi.share.weixin.message.event.LocationEventMessage;
import com.xinyi.share.weixin.message.event.ScanEventMessage;
import com.xinyi.share.weixin.message.receive.ImageReceiveMessage;
import com.xinyi.share.weixin.message.receive.LinkReceiveMessage;
import com.xinyi.share.weixin.message.receive.LocationReceiveMessage;
import com.xinyi.share.weixin.message.receive.TextReceiveMessage;
import com.xinyi.share.weixin.message.receive.VideoReceiveMessage;
import com.xinyi.share.weixin.message.receive.VoiceReceiveMessage;
import com.xinyi.share.weixin.message.reply.Article;
import com.xinyi.share.weixin.message.reply.MediaReplyMessage;
import com.xinyi.share.weixin.message.reply.MusicReplyMessage;
import com.xinyi.share.weixin.message.reply.NewsReplyMessage;
import com.xinyi.share.weixin.message.reply.TextReplyMessage;


/**
 * 消息工厂
 * 
 * @author wangchuan
 * 
 */
public final class MessageFactory {
	private MessageFactory() {
	}
	
	/**
	 * 
	 * @description 获取消息类型
	 * @param root
	 * @return
	 * @return ReceiveMessage
	 * @author wangchuan
	 * @throws
	 */
	public static Message getReceiveMessage(Element root) {
		Element msgTypeElement = root.element("MsgType");
		String msgtype = msgTypeElement.getTextTrim();
		switch (msgtype) {
		case Message.text:
			return getTextMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("Content").getTextTrim(),
					Long.parseLong(root.element("CreateTime").getTextTrim()));
		case Message.image:
			return getImageMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("PicUrl").getTextTrim(),
					root.element("MediaId").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
		case Message.voice:
			return getVoiceReceiveMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("MediaId")
					.getTextTrim(), root.element("Format").getTextTrim(),(null==root.element("Recognition")?"":root.element("Recognition").getTextTrim()), Long.parseLong(root.element("CreateTime").getTextTrim()));
		case Message.video:
			return getVideoReceiveMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("MediaId")
					.getTextTrim(), root.element("ThumbMediaId").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
		case Message.location:
			return getLocationReceiveMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("Location_X")
					.getTextTrim(), root.element("Location_Y").getTextTrim(), Integer.parseInt(root.element("Scale").getTextTrim()), root.element("Label").getTextTrim(), Long.parseLong(root.element(
					"CreateTime").getTextTrim()));
		case Message.link:
			return getLinkReceiveMessage(root.element("MsgId").getTextTrim(), root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(),
					root.element("Title").getTextTrim(), root.element("Description").getTextTrim(), root.element("Url").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
		case Message.eventtype:return getEventMessage(root);
		default:
			return null;
		}
	}
	
	/**
	 * 
	 * @description 获取返回XML
	 * @param message
	 * @return
	 * @return StringBuilder
	 * @author wangchuan
	 * @throws
	 */
	public static String getReplyMessageXml(Message message){
		StringBuilder builder = new StringBuilder("<xml>");
		builder.append("<ToUserName>").append(message.getToUserName()).append("</ToUserName>");
		builder.append("<FromUserName>").append(message.getFromUserName()).append("</FromUserName>");
		builder.append("<CreateTime>").append(message.getCreateTime()).append("</CreateTime>");
		builder.append("<MsgType>").append(message.getMsgType()).append("</MsgType>");
		if(message instanceof TextReplyMessage){
			builder.append(getReplyMessageContent((TextReplyMessage)message));
		}else if(message instanceof MediaReplyMessage){
			builder.append(getReplyMessageContent((MediaReplyMessage)message));
		}else if(message instanceof NewsReplyMessage){
			builder.append(getReplyMessageContent((NewsReplyMessage)message));
		}else if(message instanceof MusicReplyMessage){
			builder.append(getReplyMessageContent((MusicReplyMessage)message));
		}
		builder.append("</xml>");
		return builder.toString();
	}
	/**
	 * 
	 * @description 获取文本内容
	 * @param textReplyMessage
	 * @return
	 * @return String
	 * @author wangchuan
	 * @throws
	 */
	private static StringBuilder getReplyMessageContent(TextReplyMessage textReplyMessage){
		StringBuilder contentBuilder = new StringBuilder();
		contentBuilder.append("<Content>").append(textReplyMessage.getContent()).append("</Content>");
		return contentBuilder;
	}
	/**
	 * 
	 * @description 获取图片、语音消息
	 * @param mediaReplyMessage
	 * @return
	 * @return StringBuilder
	 * @author wangchuan
	 * @throws
	 */
	private static StringBuilder getReplyMessageContent(MediaReplyMessage mediaReplyMessage){
		StringBuilder contentBuilder = new StringBuilder();
		String type = StringUtils.equals(Message.image, mediaReplyMessage.getMsgType())?"Image":StringUtils.equals(Message.voice, mediaReplyMessage.getMsgType())?"Voice":"Video";
		contentBuilder.append("<").append(type).append(">");
		contentBuilder.append("<MediaId>").append(mediaReplyMessage.getMediaid()).append("</MediaId>");
		if(StringUtils.equals(Message.video, mediaReplyMessage.getMsgType())){
			contentBuilder.append("<Title>").append(mediaReplyMessage.getTitle()).append("</Title>");
			contentBuilder.append("<Description>").append(mediaReplyMessage.getDescription()).append("</Description>");
		}
		contentBuilder.append("</").append(type).append(">");
		return contentBuilder;
	}
	/**
	 * 
	 * @description 返回音乐消息
	 * @param musicReplyMessage
	 * @return
	 * @return StringBuilder
	 * @author wangchuan
	 * @throws
	 */
	private static StringBuilder getReplyMessageContent(MusicReplyMessage musicReplyMessage){
		StringBuilder contentBuilder = new StringBuilder();
		contentBuilder.append("<Music>");
		contentBuilder.append("<Title>").append(musicReplyMessage.getTitle()).append("</Title>");
		contentBuilder.append("<Description>").append(musicReplyMessage.getDescription()).append("</Description>");
		contentBuilder.append("<MusicUrl>").append(musicReplyMessage.getDescription()).append("</MusicUrl>");
		contentBuilder.append("<HQMusicUrl>").append(musicReplyMessage.getDescription()).append("</HQMusicUrl>");
		contentBuilder.append("<ThumbMediaId>").append(musicReplyMessage.getDescription()).append("</ThumbMediaId>");
		contentBuilder.append("</Music>");
		return contentBuilder;
	}
	/**
	 * 
	 * @description 新闻回复消息
	 * @param newsReplyMessage
	 * @return
	 * @return StringBuilder
	 * @author wangchuan
	 * @throws
	 */
	private static StringBuilder getReplyMessageContent(NewsReplyMessage newsReplyMessage){
		StringBuilder contentBuilder = new StringBuilder();
		contentBuilder.append("<ArticleCount>").append(newsReplyMessage.getArticlecount()).append("</ArticleCount>");
		contentBuilder.append("<Articles>");
		List<Article> articles = newsReplyMessage.getArticles();
		for(Article Article:articles){
			contentBuilder.append("<item>");
			contentBuilder.append("<Title>").append(Article.getTitle()).append("</Title>");
			contentBuilder.append("<Description>").append(Article.getDescription()).append("</Description>");
			contentBuilder.append("<PicUrl>").append(Article.getPicurl()).append("</PicUrl>");
			contentBuilder.append("<Url>").append(Article.getUrl()).append("</Url>");
			contentBuilder.append("</item>");
		}
		contentBuilder.append("</Articles>");
		return contentBuilder;
	}
	/**
	 * 
	 * @description 事件类型
	 * @param root
	 * @return
	 * @return EventMessage
	 * @author wangchuan
	 * @throws
	 */
	private static EventMessage getEventMessage(Element root){
		String eventstr = root.element("Event").getTextTrim();
		Event event = Event.valueOf(eventstr);
		switch (event) {
			case VIEW:
				return new ClickEventMessage(root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), Event.VIEW.toString(),root.element("EventKey").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
			case CLICK:
				return new ClickEventMessage(root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), Event.CLICK.toString(),root.element("EventKey").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
			case SCAN:
				return new ScanEventMessage(root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("EventKey").getTextTrim(),root.element("Ticket").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
			case LOCATION:
				return new LocationEventMessage(root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), root.element("Latitude").getTextTrim(), root.element("Longitude").getTextTrim(), root.element("Precision").getTextTrim(), Long.parseLong(root.element("CreateTime").getTextTrim()));
			case UNSUBSCRIBE:;
			case SUBSCRIBE:
				return new EventMessage(root.element("FromUserName").getTextTrim(), root.element("ToUserName").getTextTrim(), event.toString(), Long.parseLong(root.element("CreateTime").getTextTrim()));
			default:return null;
		}
	}

	/**
	 * 
	 * @description 返回文字消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param createTime
	 * @param content
	 * @return TextMessage
	 * @author wangchuan
	 * @throws
	 */
	private static TextReceiveMessage getTextMessage(String msgId, String fromUserName, String toUserName, String content, long createTime) {
		return new TextReceiveMessage(msgId, fromUserName, toUserName, createTime, content);
	}

	/**
	 * 
	 * @description 返回图片消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param picurl
	 * @param mediaid
	 * @param createTime
	 * @return ImageMessage
	 * @author wangchuan
	 * @throws
	 */
	private static ImageReceiveMessage getImageMessage(String msgId, String fromUserName, String toUserName, String picurl, String mediaid, long createTime) {
		return new ImageReceiveMessage(msgId, fromUserName, toUserName, picurl, mediaid, createTime);
	}

	/**
	 * 
	 * @description 获取声音消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param mediaid
	 * @param format
	 * @param createTime
	 * @return
	 * @return VoiceReceiveMessage
	 * @author wangchuan
	 * @throws
	 */
	private static VoiceReceiveMessage getVoiceReceiveMessage(String msgId, String fromUserName, String toUserName, String mediaid, String format, String recognition,  long createTime) {
		return new VoiceReceiveMessage(msgId, fromUserName, toUserName, mediaid, format, recognition, createTime);
	}

	/**
	 * 
	 * @description 获取视频消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param mediaid
	 * @param thumbmediaid
	 * @param createTime
	 * @return VideoReceiveMessage
	 * @author wangchuan
	 * @throws
	 */
	private static VideoReceiveMessage getVideoReceiveMessage(String msgId, String fromUserName, String toUserName, String mediaid, String thumbmediaid, long createTime) {
		return new VideoReceiveMessage(msgId, fromUserName, toUserName, mediaid, thumbmediaid, createTime);
	}

	/**
	 * 
	 * @description 获取位置消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param locationx
	 * @param locationy
	 * @param scale
	 * @param label
	 * @param createTime
	 * @return
	 * @return LocationReceiveMessage
	 * @author wangchuan
	 * @throws
	 */
	private static LocationReceiveMessage getLocationReceiveMessage(String msgId, String fromUserName, String toUserName, String locationx, String locationy, int scale, String label, long createTime) {
		return new LocationReceiveMessage(msgId, fromUserName, toUserName, locationx, locationy, scale, label, createTime);
	}

	/**
	 * 
	 * @description 获取超链接消息
	 * @param msgId
	 * @param fromUserName
	 * @param toUserName
	 * @param title
	 * @param description
	 * @param url
	 * @param createTime
	 * @return
	 * @return LinkReceiveMessage
	 * @author wangchuan
	 * @throws
	 */
	private static LinkReceiveMessage getLinkReceiveMessage(String msgId, String fromUserName, String toUserName, String title, String description, String url, long createTime) {
		return new LinkReceiveMessage(msgId, fromUserName, toUserName, title, description, url, createTime);
	}
}
